package cn.yunlang.zhangZhongFei.util;

import java.util.Collection;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

@Component
@Slf4j
public final class RedisUtil {
  @Resource private StringRedisTemplate stringRedisTemplate;

  public boolean expire(String key, long time) {
    try {
      if (time > 0) {
        stringRedisTemplate.expire(key, time, TimeUnit.SECONDS);
      }
      return true;
    } catch (Exception e) {
      e.printStackTrace();
      return false;
    }
  }

  public boolean set(String key, String value, long time) {
    try {
      if (time > 0) {
        stringRedisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
      } else {
        set(key, value);
      }
      return true;
    } catch (Exception e) {
      e.printStackTrace();
      return false;
    }
  }

  @SuppressWarnings("unchecked")
  public void del(String... key) {
    if (key != null && key.length > 0) {
      if (key.length == 1) {
        stringRedisTemplate.delete(key[0]);
      } else {
        stringRedisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));
      }
    }
  }

  public void delAll(String keyPath) {
    Set<String> keys = stringRedisTemplate.keys(keyPath + ":*");
    if (keys != null && !keys.isEmpty()) {
      stringRedisTemplate.delete(keys);
    } else {
    }
  }

  public String get(String key) {
    return key == null ? null : stringRedisTemplate.opsForValue().get(key);
  }

  public boolean set(String key, String value) {
    try {
      stringRedisTemplate.opsForValue().set(key, value);
      return true;
    } catch (Exception e) {
      e.printStackTrace();
      return false;
    }
  }

  public long incr(String key, long delta) {
    if (delta < 0) {
      throw new RuntimeException("递增因子必须大于0");
    }
    return stringRedisTemplate.opsForValue().increment(key, delta);
  }

  public long decr(String key, long delta) {
    if (delta < 0) {
      throw new RuntimeException("递减因子必须大于0");
    }
    return stringRedisTemplate.opsForValue().increment(key, -delta);
  }

  // ================================Map=================================

  public String hget(String key, String item) {
    return (String) stringRedisTemplate.opsForHash().get(key, item);
  }

  public boolean hset(String key, String item, String value, long time) {
    try {
      stringRedisTemplate.opsForHash().put(key, item, value);
      if (time > 0) {
        expire(key, time);
      }
      return true;
    } catch (Exception e) {
      e.printStackTrace();
      return false;
    }
  }

  /**
   * 向Set中添加元素
   *
   * @param key 键
   * @param value 值
   * @return 是否成功
   */
  public boolean sAdd(String key, String value) {
    try {
      return stringRedisTemplate.opsForSet().add(key, value) > 0;
    } catch (Exception e) {
      log.error("Redis sAdd error: key={}, value={}", key, value, e);
      return false;
    }
  }

  /**
   * 获取Set中的所有元素
   *
   * @param key 键
   * @return Set集合
   */
  public Set<String> sMembers(String key) {
    try {
      return stringRedisTemplate.opsForSet().members(key);
    } catch (Exception e) {
      log.error("Redis sMembers error: key={}", key, e);
      return null;
    }
  }
}
